/**
 *====================================================
 * 文件名称: FinanceProcessCastor.java
 * 修订记录：
 * No    日期				作者(操作:具体内容)
 * 1.    2015年10月25日			chenxy(创建:创建文件)
 *====================================================
 * 类描述：(说明未实现或其它不应生成javadoc的内容)
 */
package com.yuexunit.finance.project.action.v1.dto;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.yuexunit.finance.context.FinanceConstant;
import com.yuexunit.finance.context.FinanceSessionContext;
import com.yuexunit.finance.member.entity.EnterpriseEntity;
import com.yuexunit.finance.member.service.EnterpriseService;
import com.yuexunit.finance.member.service.LogisticsCompanyService;
import com.yuexunit.finance.project.action.v1.model.output.ContainerBulkstock;
import com.yuexunit.finance.project.entity.ContainerBulkstockEntity;
import com.yuexunit.finance.project.entity.ContainerInventoryEntity;
import com.yuexunit.finance.project.entity.DeliveryEntity;
import com.yuexunit.finance.project.entity.DeliveryNoticeEntity;
import com.yuexunit.finance.project.entity.FinanceApplicationEntity;
import com.yuexunit.finance.project.entity.FinanceProcessDetailEntity;
import com.yuexunit.finance.project.entity.FinanceProcessEntity;
import com.yuexunit.finance.project.entity.LoanNoticeEntity;
import com.yuexunit.finance.project.entity.PickupApplicationEntity;
import com.yuexunit.finance.project.entity.PickupBulkstockEntity;
import com.yuexunit.finance.project.entity.PickupDelayApplicationEntity;
import com.yuexunit.finance.project.entity.ReceivablesEntity;
import com.yuexunit.finance.project.entity.RecieveNoticeEntity;
import com.yuexunit.finance.project.entity.RecieveNoticeInventoryEntity;
import com.yuexunit.finance.project.entity.SupervisionConfirmationEntity;
import com.yuexunit.finance.project.entity.TallyingEntity;
import com.yuexunit.finance.project.entity.TransportNoticeEntity;
import com.yuexunit.finance.project.entity.lexicon.BusinessTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.OperatorRoleEnum;
import com.yuexunit.finance.project.entity.lexicon.PickupTypeEnum;
import com.yuexunit.finance.project.entity.lexicon.ProcessSegmentEnum;
import com.yuexunit.finance.project.entity.lexicon.ProcessTypeEnum;
import com.yuexunit.finance.project.service.ContainerBulkstockService;
import com.yuexunit.finance.project.service.ContainerInventoryService;
import com.yuexunit.finance.project.service.FinanceApplicationService;
import com.yuexunit.finance.project.service.FinanceBulkstockService;
import com.yuexunit.finance.project.service.FinanceProcessDetailService;
import com.yuexunit.finance.project.service.FinanceProcessService;
import com.yuexunit.finance.project.service.PickupBulkstockService;
import com.yuexunit.inject.ComponentFactory;
import com.yuexunit.util.DateUtil;

/**
 * @ClassName: FinanceProcessCastor
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author chenxy
 * @date 2015年10月25日 下午12:10:06
 */
public class FinanceProcessCastor {

	private static FinanceApplicationService financeApplicationService = ComponentFactory.loadClass(FinanceApplicationService.class);

	private static FinanceProcessService financeProcessService = ComponentFactory.loadClass(FinanceProcessService.class);

	private static FinanceProcessDetailService financeProcessDetailService = ComponentFactory.loadClass(FinanceProcessDetailService.class);
	
	private static EnterpriseService enterpriseService = ComponentFactory.loadClass(EnterpriseService.class);

	private static FinanceProcessEntity createFinanceProcessEntity(Long financeId, String financeNumber, ProcessTypeEnum processType, ProcessSegmentEnum processSegment, Long businessId, BusinessTypeEnum businessType, String businessVoucher,
			String description) {
		OperatorRoleEnum operatorRole = OperatorRoleEnum.valueOf(FinanceConstant.APP_ROLE.get(FinanceSessionContext.getAppKey()));
		FinanceProcessEntity entity = new FinanceProcessEntity();
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(financeId);
		EnterpriseEntity enterprise = enterpriseService.inquireEnterprise(finance.getEnterpriseId());
		entity.setFinanceId(financeId);
		entity.setFinanceNumber(financeNumber);
		entity.setProcessType(processType);
		entity.setProcessSegment(processSegment);
		entity.setOperatorId(enterprise.getAccountId());
		entity.setOperator(enterprise.getEnterpriseName());
		entity.setOperatorRole(operatorRole);
		entity.setBusinessId(businessId);
		entity.setBusinessType(businessType);
		entity.setBusinessVoucher(businessVoucher);
		entity.setDescription(description);
		entity.setWeight(BigDecimal.ZERO);
		return entity;
	}

	/** 创建动态信息-融资申请 */
	public static FinanceProcessEntity fromFinanceSubmitProcess(Long financeId, String financeNumber) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.APPLICATION;
		BusinessTypeEnum businessType = BusinessTypeEnum.FINANCE;
		String businessVoucher = "--";
		String description = "提交借款申请";
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, financeId, businessType, businessVoucher, description);
		process.setSegment("融资项目申请");
		return process;
	}

	/** 创建动态信息-融资取消 */
	public static FinanceProcessEntity fromFinanceCancelProcess(Long financeId, String financeNumber) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.APPLICATION;
		BusinessTypeEnum businessType = BusinessTypeEnum.FINANCE;
		String businessVoucher = "--";
		String description = "取消借款申请";
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, financeId, businessType, businessVoucher, description);
		process.setSegment("融资项目取消");
		return process;
	}

	/** 创建动态信息-融资申请审核 */
	public static FinanceProcessEntity fromFinanceAuditProcess(Long financeId, String financeNumber, Long financeAuditId) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.FINANCE_AUDIT;
		BusinessTypeEnum businessType = BusinessTypeEnum.FINANCE_AUDIT;
		String businessVoucher = "《融资审核单》";
		String description = "融资申请审批未通过";
		if (financeAuditId != null) {
			description = "融资申请审批通过";
		}
		Long businessId = financeAuditId;
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
		process.setSegment("融资申请审核");
		return process;
	}

	/** 创建动态信息-合同拟定 */
	public static FinanceProcessEntity fromFinanceContractProcess(Long financeId, String financeNumber, Long constractId) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.CONSTRACT;
		BusinessTypeEnum businessType = BusinessTypeEnum.FINANCE_CONTRACT;
		String businessVoucher = "《融资合同》";
		String description = "合同签订";
		Long businessId = constractId;
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
		process.setSegment("融资合同签订");
		return process;
	}

	/** 创建动态信息-监管合同拟定 */
	public static FinanceProcessEntity fromSupervisionContractProcess(Long financeId, String financeNumber, Long supervisionContractId) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.CONSTRACT;
		BusinessTypeEnum businessType = BusinessTypeEnum.SUPERVISION_CONTRACT;
		String businessVoucher = "《监管合同》";
		String description = "监管合同签订";
		Long businessId = supervisionContractId;
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
		process.setSegment("监管合同签订");
		return process;
	}

	/** 创建动态信息-监管合同拟定 */
	public static FinanceProcessEntity fromSupervisionNoticeProcess(Long financeId, String financeNumber, Long supervisionNoticeId) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINANCE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.CONSTRACT;
		BusinessTypeEnum businessType = BusinessTypeEnum.SUPERVISION_NOTICE;
		String businessVoucher = "《监管通知》";
		String description = "监管通知下达";
		Long businessId = supervisionNoticeId;
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
		process.setSegment("监管通知下达");
		return process;
	}

	/** 创建动态信息-发货通知 */
	public static FinanceProcessEntity fromFinanceRecieveNoticeProcess(RecieveNoticeEntity recieveNotice, List<RecieveNoticeInventoryEntity> inventories) {
		StringBuffer description = new StringBuffer("已通知发货 数量:");
		int quantity = 0;
		for (RecieveNoticeInventoryEntity inventory : inventories) {
			quantity = quantity + inventory.getQuantity().intValue();
		}
		description.append(quantity).append(inventories.get(0).getUnit());
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.NOTICE_RECIEVE;
		Long businessId = recieveNotice.getRecieveNoticeId();
		BusinessTypeEnum businessType = BusinessTypeEnum.RECIEVE_NOTICE;
		String businessVoucher = "《交货通知单》";
		FinanceProcessEntity process = createFinanceProcessEntity(recieveNotice.getFinanceId(), recieveNotice.getFinanceNumber(), processType, processSegment, businessId, businessType, businessVoucher, description.toString());
		return process;
	}

	/** 创建动态信息-收货(理货上报) */
	public static FinanceProcessEntity fromFinanceRecieveProcess(TallyingEntity tallying) {
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.RECIEVE;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(tallying.getFinanceId(), processType, processSegment);
		if (process == null) {
			String businessVoucher = null;
			String description = null;
			process = createFinanceProcessEntity(tallying.getFinanceId(), tallying.getFinanceNumber(), processType, processSegment, tallying.getTallyingId(), BusinessTypeEnum.TALLYING, businessVoucher, description);
			process.setRecieve(BigDecimal.ZERO);
			FinanceApplicationEntity financeEntity = financeApplicationService.inquireFinanceApplicationEntity(tallying.getFinanceId());
			process.setReceiveCity(financeEntity.getReceiveCity());
		}
		process.setBusinessId(tallying.getTallyingId());

		FinanceProcessDetailEntity currentDetail = new FinanceProcessDetailEntity();
		currentDetail.setBusinessId(tallying.getTallyingId());
		currentDetail.setBusinessType(BusinessTypeEnum.TALLYING);
		currentDetail.setBusinessVoucher("《理货清单》");
		StringBuffer sb = new StringBuffer();
		sb.append(process.getReceiveCity()).append(" 发");

		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		LogisticsCompanyService logisticsCompanyService = ComponentFactory.loadClass(LogisticsCompanyService.class);
		List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireTallyingContainerBulkstockList(tallying.getTallyingId());
		Map<Long, ContainerBulkstock> ds = new HashMap<>();
		String unit = "件";
		for (ContainerBulkstockEntity bie : containerBulkstockList) {
			ContainerBulkstock bi = ds.get(bie.getBulkstockId());
			if (bi == null) {
				bi = new ContainerBulkstock();
				bi.setQuantity(bie.getQuantity());
				bi.setUnit(bie.getUnit());
				bi.setBulkstockName(bie.getBulkstockName());
				bi.setSpecification(bie.getSpecification());
				ds.put(bi.getBulkstockId(), bi);
			} else {
				bi.setQuantity(bi.getQuantity().add(bie.getQuantity()));
			}
			if (bie.getQuantity() == null) {
				bie.setQuantity(BigDecimal.ZERO);
			}
			process.setRecieve(process.getRecieve().add(bie.getQuantity()));
		}
		for (Entry<Long, ContainerBulkstock> e : ds.entrySet()) {
			ContainerBulkstock bi = e.getValue();
			sb.append(" ").append(bi.getBulkstockName()).append(bi.getSpecification()).append(bi.getQuantity()).append(bi.getUnit());
			unit = bi.getUnit();
		}
		currentDetail.setDescription(sb.toString());
		currentDetail.setOperator(logisticsCompanyService.inquireTenantLogisticsCompanyByAccountId(FinanceSessionContext.getAccountId()).getCompanyName());
		currentDetail.setOperatorId(FinanceSessionContext.getAccountId());
		currentDetail.setOperatorRole(OperatorRoleEnum.LOGISTICS);
		process.setCurrentDetail(currentDetail);
		process.setSegment(String.format("发货:%s,共发货 %s %s", process.getReceiveCity(), process.getRecieve(), unit));
		return process;
	}

	/** 创建动态信息-质押(理货监管确认) */
	public static FinanceProcessEntity fromFinanceSupervisionProcess(SupervisionConfirmationEntity supervision) {
		Long financeId = supervision.getFinanceId();
		String financeNumber = supervision.getFinanceNumber();
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.SUPERVISION;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(financeId, processType, processSegment);
		if (process == null) {
			String businessVoucher = null;
			String description = null;
			process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, supervision.getConfirmationId(), BusinessTypeEnum.SUPERVISION_CONFIRMATION, businessVoucher, description);
			process.setSupervision(BigDecimal.ZERO);
		}
		process.setBusinessId(supervision.getConfirmationId());

		FinanceProcessDetailEntity currentDetail = new FinanceProcessDetailEntity();
		currentDetail.setBusinessId(supervision.getConfirmationId());
		currentDetail.setBusinessType(BusinessTypeEnum.SUPERVISION_CONFIRMATION);
		currentDetail.setBusinessVoucher("《监管确认书》");

		StringBuffer sb = new StringBuffer("确认监管");
		ContainerInventoryService containerInventoryService = ComponentFactory.loadClass(ContainerInventoryService.class);
		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		List<ContainerInventoryEntity> inventories = containerInventoryService.inquireSupervisionConfirmationContainerInventoryList(supervision.getConfirmationId());
		Map<Long, ContainerBulkstock> ds = new HashMap<>();
		String unit = "件";
		for (ContainerInventoryEntity cie : inventories) {
			List<ContainerBulkstockEntity> bulkstocks = containerBulkstockService.inquireContainerBulkstockList(cie.getInventoryId());
			for (ContainerBulkstockEntity cbe : bulkstocks) {
				ContainerBulkstock bi = ds.get(cbe.getBulkstockId());
				if (bi == null) {
					bi = new ContainerBulkstock();
					bi.setQuantity(BigDecimal.ZERO);
					bi.setUnit(cbe.getUnit());
					bi.setBulkstockName(cbe.getBulkstockName());
					bi.setSpecification(cbe.getSpecification());
				}
				bi.setQuantity(bi.getQuantity().add(cbe.getQuantity()));
				ds.put(bi.getBulkstockId(), bi);
				process.setSupervision(process.getSupervision().subtract(cbe.getQuantity()));
			}
		}
		for (Entry<Long, ContainerBulkstock> e : ds.entrySet()) {
			ContainerBulkstock bi = e.getValue();
			sb.append(" ").append(bi.getBulkstockName()).append(bi.getSpecification()).append(bi.getQuantity()).append(bi.getUnit());
			unit = bi.getUnit();
		}
		currentDetail.setDescription(sb.toString());
		currentDetail.setOperator(FinanceSessionContext.getAccountFullName());
		currentDetail.setOperatorId(FinanceSessionContext.getAccountId());
		currentDetail.setOperatorRole(OperatorRoleEnum.PLATFORM);
		process.setCurrentDetail(currentDetail);
		process.setSegment(String.format("质押:共已质押监管 %s %s", process.getSupervision(), unit));
		return process;
	}

	/** 创建动态信息-放款审核(放款通知书) */
	public static FinanceProcessEntity fromFinanceLoanProcess(LoanNoticeEntity loanNotice, LoanNoticeEntity persist) {
		if (loanNotice.getLoanAmountAlready() == null) {
			loanNotice.setLoanAmountAlready(BigDecimal.ZERO);
		}
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.LOAN;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(loanNotice.getFinanceId(), processType, processSegment);
		if (process == null) {
			String businessVoucher = null;
			String description = null;
			Long businessId = loanNotice.getLoanNoticeId();
			BusinessTypeEnum businessType = BusinessTypeEnum.LOAN_NOTICE;

			process = createFinanceProcessEntity(loanNotice.getFinanceId(), loanNotice.getFinanceNumber(), processType, processSegment, businessId, businessType, businessVoucher, description);
			process.setLoan(BigDecimal.ZERO);
			process.setLoanAlready(BigDecimal.ZERO);
		}
		process.setBusinessId(loanNotice.getLoanNoticeId());

		FinanceProcessDetailEntity currentDetail = new FinanceProcessDetailEntity();
		currentDetail.setBusinessId(loanNotice.getLoanNoticeId());
		currentDetail.setBusinessType(BusinessTypeEnum.LOAN_NOTICE);
		currentDetail.setBusinessVoucher("《放款申请单》");
		if (persist == null) {
			process.setLoan(process.getLoan().add(loanNotice.getLoanAmount()));
			process.setLoan(process.getLoanAlready().add(loanNotice.getLoanAmountAlready()));
			// currentDetail.setDescription(String.format("确认放款 ￥%.2f", loanNotice.getLoanAmount()));
			currentDetail.setDescription("放款申请已经批准");
		} else {
			process.setLoan(process.getLoan().add(loanNotice.getLoanAmount()).subtract(persist.getLoanAmount()));
			currentDetail.setDescription(String.format("放款调整 原￥%.2d调整为 ￥%.2d", persist.getLoanAmount(), loanNotice.getLoanAmount()));
		}
		currentDetail.setOperator(FinanceSessionContext.getAccountFullName());
		currentDetail.setOperatorId(FinanceSessionContext.getAccountId());
		currentDetail.setOperatorRole(OperatorRoleEnum.PLATFORM);

		process.setSegment(String.format("放款:共已确认放款 ￥%.2f", process.getLoanAlready()));
		process.setCurrentDetail(currentDetail);
		return process;
	}

	/** 创建动态信息-放款核销(放款通知书) */
	public static FinanceProcessEntity fromFinanceLoanVerify(LoanNoticeEntity loanNotice) {
		if (loanNotice.getLoanAmountAlready() == null) {
			loanNotice.setLoanAmountAlready(BigDecimal.ZERO);
		}
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.LOAN;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(loanNotice.getFinanceId(), processType, processSegment);
		if (process == null) {
			String businessVoucher = null;
			String description = null;
			Long businessId = loanNotice.getLoanNoticeId();
			BusinessTypeEnum businessType = BusinessTypeEnum.LOAN_NOTICE;

			process = createFinanceProcessEntity(loanNotice.getFinanceId(), loanNotice.getFinanceNumber(), processType, processSegment, businessId, businessType, businessVoucher, description);
			process.setLoan(BigDecimal.ZERO);
			process.setLoanAlready(BigDecimal.ZERO);
		}
		process.setBusinessId(loanNotice.getLoanNoticeId());
		if (process.getLoanAlready() == null) {
			process.setLoanAlready(BigDecimal.ZERO);
		}

		FinanceProcessDetailEntity currentDetail = new FinanceProcessDetailEntity();
		currentDetail.setBusinessId(loanNotice.getLoanNoticeId());
		currentDetail.setBusinessType(BusinessTypeEnum.LOAN_NOTICE);
		currentDetail.setBusinessVoucher("《放款单》");
		process.setLoanAlready(process.getLoanAlready().add(loanNotice.getLoanAmountAlready()));
		currentDetail.setDescription(String.format("确认放款 ￥%.2f", loanNotice.getLoanAmountAlready()));
		currentDetail.setOperator(FinanceSessionContext.getAccountFullName());
		currentDetail.setOperatorId(FinanceSessionContext.getAccountId());
		currentDetail.setOperatorRole(OperatorRoleEnum.PLATFORM);

		process.setSegment(String.format("放款:共已确认放款 ￥%.2f", process.getLoanAlready()));
		process.setCurrentDetail(currentDetail);
		return process;
	}

	/** 创建动态信息-运输通知(运输通知确认) */
	public static FinanceProcessEntity fromFinanceTransportProcess(TransportNoticeEntity transportNotice) {
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.TRANSPORT;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(transportNotice.getFinanceId(), processType, processSegment);
		if (process == null) {
			Long financeId = transportNotice.getFinanceId();
			String financeNumber = transportNotice.getFinanceNumber();
			Long businessId = transportNotice.getTransportNoticeId();
			String businessVoucher = null;
			String description = null;
			BusinessTypeEnum businessType = BusinessTypeEnum.TRANSPORT_NOTICE;

			process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
			process.setTransport(BigDecimal.ZERO);
			FinanceApplicationEntity financeEntity = financeApplicationService.inquireFinanceApplicationEntity(transportNotice.getFinanceId());
			process.setReceiveCity(financeEntity.getReceiveCity());
			process.setDeliverCity(financeEntity.getDeliverCity());
		}
		process.setBusinessId(transportNotice.getTransportNoticeId());

		ContainerInventoryService containerInventoryService = ComponentFactory.loadClass(ContainerInventoryService.class);
		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		List<ContainerInventoryEntity> containerInventoryList = containerInventoryService.inquireTransportContainerInventoryList(transportNotice.getTransportNoticeId());
		List<FinanceProcessDetailEntity> currentDetails = new ArrayList<>();
		for (ContainerInventoryEntity cie : containerInventoryList) {
			FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
			detail.setBusinessId(cie.getInventoryId());
			detail.setBusinessType(BusinessTypeEnum.CONTAINER_INVENTORY);
			detail.setSegment("箱号:" + cie.getCaseNumber());
			detail.setDescription(cie.getCaseSize() + " " + process.getDeliverCity() + " - " + process.getReceiveCity());
			detail.setBusinessVoucher("《箱货明细》");
			detail.setOperator(FinanceSessionContext.getAccountFullName());
			detail.setOperatorId(FinanceSessionContext.getAccountId());
			detail.setOperatorRole(OperatorRoleEnum.LOGISTICS);
			List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireContainerBulkstockList(cie.getInventoryId());
			for (ContainerBulkstockEntity cbe : containerBulkstockList) {
				process.setTransport(process.getTransport().add(cbe.getQuantity()));
			}
			currentDetails.add(detail);
		}
		process.setCurrentDetails(currentDetails);
		process.setSegment(String.format("运输:海运在途 %s 件", process.getTransport()));
		return process;
	}

	/** 创建动态信息-到港 */
	public static FinanceProcessEntity fromFinanceArriveProcess(TransportNoticeEntity entity) {
		ContainerInventoryService containerInventoryService = ComponentFactory.loadClass(ContainerInventoryService.class);
		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		ProcessTypeEnum processType = ProcessTypeEnum.LOAN;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.TRANSPORT;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(entity.getFinanceId(), processType, processSegment);
		List<ContainerInventoryEntity> containerInventoryList = containerInventoryService.inquireTransportContainerInventoryList(entity.getTransportNoticeId());
		if (process != null) {
			for (ContainerInventoryEntity cie : containerInventoryList) {
				List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireContainerBulkstockList(cie.getInventoryId());
				for (ContainerBulkstockEntity cbe : containerBulkstockList) {
					process.setTransport(process.getTransport().subtract(cbe.getQuantity()));
				}
			}
			process.setSegment(String.format("运输:海运在途 %s 件", process.getTransport()));
			financeProcessService.renovateFinanceProcess(process);
		}

		processType = ProcessTypeEnum.PLEDGE;
		processSegment = ProcessSegmentEnum.ARRIVE;
		process = financeProcessService.inquireFinanceProcess(entity.getFinanceId(), processType, processSegment);
		if (process == null) {
			Long financeId = entity.getFinanceId();
			String financeNumber = entity.getFinanceNumber();
			Long businessId = entity.getTransportNoticeId();
			BusinessTypeEnum businessType = BusinessTypeEnum.TRANSPORT_NOTICE;
			String businessVoucher = null;
			String description = null;
			process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
			process.setArrive(BigDecimal.ZERO);
			process.setPickup(BigDecimal.ZERO);
			process.setSign(BigDecimal.ZERO);
			process.setPickupable(BigDecimal.ZERO);
			process.setWeight(BigDecimal.ZERO);
			process.setVolume(BigDecimal.ZERO);
		}
		process.setBusinessId(entity.getTransportNoticeId());
		process.setBusinessType(BusinessTypeEnum.TRANSPORT_NOTICE);
		if (process.getWeight() == null) {
			process.setWeight(BigDecimal.ZERO);
		}
		if (process.getVolume() == null) {
			process.setVolume(BigDecimal.ZERO);
		}
		for (ContainerInventoryEntity cie : containerInventoryList) {
			List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireContainerBulkstockList(cie.getInventoryId());
			for (ContainerBulkstockEntity cbe : containerBulkstockList) {
				process.setArrive(process.getArrive().add(cbe.getQuantity()));
				process.setWeight(process.getWeight().add(cbe.getWeight()));
				process.setVolume(process.getVolume().add(cbe.getVolume() == null ? BigDecimal.valueOf(0) : cbe.getVolume()));
				process.setPickupable(process.getPickupable().add(cbe.getQuantity()));
			}
		}
		FinanceBulkstockService financeBulkstockService = ComponentFactory.loadClass(FinanceBulkstockService.class);
		BigDecimal abnormal = financeBulkstockService.countAbnormalBulkstockQuantity(entity.getFinanceId());
		process.setAbnormal(abnormal);

		process.setBusinessId(entity.getTransportNoticeId());
		String segment = "到港%s件,体积%.2f(m³),重量%.2f(kg),申请提货 %s件,已提 %s件,可提 %s件,异常 %s件";
		process.setSegment(String.format(segment, process.getArrive(), process.getVolume(), process.getWeight(), process.getPickup(), process.getSign(), process.getPickupable(), process.getAbnormal()));
		return process;
	}

	/** 创建动态信息-提货申请 */
	public static FinanceProcessEntity fromFinancePickupApplicationProcess(PickupApplicationEntity pickupEntity) {
		String pickupTypePre = "提货";
		if (PickupTypeEnum.AHEAD == pickupEntity.getPickupType()) {
			pickupTypePre = "提前还款";
		} else if (PickupTypeEnum.REDEEM == pickupEntity.getPickupType()) {
			pickupTypePre = "赎货";
		}

		PickupBulkstockService pickupBulkstockService = ComponentFactory.loadClass(PickupBulkstockService.class);
		List<PickupBulkstockEntity> pickupBulkstockList = pickupBulkstockService.inquirePickupBulkstockList(pickupEntity.getPickupId());
		BigDecimal pickup = BigDecimal.ZERO;
		for (PickupBulkstockEntity pbe : pickupBulkstockList) {
			pickup = pickup.add(pbe.getQuantity());
		}

		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.ARRIVE;
		FinanceProcessEntity arriveProcess = financeProcessService.inquireFinanceProcess(pickupEntity.getFinanceId(), processType, processSegment);
		if (arriveProcess == null) {
			Long financeId = pickupEntity.getFinanceId();
			String financeNumber = pickupEntity.getFinanceNumber();
			Long businessId = null;
			String businessVoucher = null;
			String description = null;
			BusinessTypeEnum businessType = null;
			arriveProcess = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, businessId, businessType, businessVoucher, description);
			arriveProcess.setArrive(BigDecimal.ZERO);
			arriveProcess.setPickup(BigDecimal.ZERO);
			arriveProcess.setSign(BigDecimal.ZERO);
			arriveProcess.setPickupable(BigDecimal.ZERO);
		}
		arriveProcess.setPickup(arriveProcess.getPickup().add(pickup));
		String segment = "到港%s件,体积%.2f(m³),重量%.2f(kg),申请提货 %s件,已提 %s件,可提 %s件,异常 %s件";
		arriveProcess.setSegment(
				String.format(segment, arriveProcess.getArrive(), arriveProcess.getVolume(), arriveProcess.getWeight(), arriveProcess.getPickup(), arriveProcess.getSign(), arriveProcess.getPickupable(), arriveProcess.getAbnormal()));

		// 提货申请
		processType = ProcessTypeEnum.PLEDGE;
		processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = pickupEntity.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		String businessVoucher = pickupTypePre + "明细";
		String description = String.format(pickupTypePre + " %s 件,待审核", pickup);
		FinanceProcessEntity pickupProcess = createFinanceProcessEntity(pickupEntity.getFinanceId(), pickupEntity.getFinanceNumber(), processType, processSegment, businessId, businessType, businessVoucher, description);
		pickupProcess.setPickup(pickup);
		pickupProcess.setSegment(String.format(pickupTypePre + "申请号：%s", pickupEntity.getPickupNumber()));

		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(pickupEntity.getPickupId());
		detail.setBusinessType(BusinessTypeEnum.PICKUP_APPLICATION);
		detail.setDescription("提交" + pickupTypePre + "申请");
		detail.setBusinessVoucher("《" + pickupTypePre + "申请单》");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.ENTERPRISE);

		pickupProcess.setCurrentDetail(detail);
		pickupProcess.setParentProcess(arriveProcess);
		return pickupProcess;

	}

	/** 创建动态信息-提货申请-审核 */
	public static FinanceProcessEntity fromFinancePickupAuditProcess(PickupApplicationEntity pickupEntity, Boolean audit) {
		String pickupTypePre = "提货";
		if (PickupTypeEnum.AHEAD == pickupEntity.getPickupType()) {
			pickupTypePre = "提前还款";
		} else if (PickupTypeEnum.REDEEM == pickupEntity.getPickupType()) {
			pickupTypePre = "赎货";
		}
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = pickupEntity.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(pickupEntity.getFinanceId(), businessId, businessType, processType, processSegment);
		if (!audit) {
			pickupProcess.setDescription(String.format(pickupTypePre + " %s 件,审核未通过", pickupProcess.getPickup()));
			// 明细记录
			FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
			detail.setBusinessId(pickupEntity.getPickupId());
			detail.setBusinessType(BusinessTypeEnum.PICKUP_APPLICATION);
			detail.setDescription("提交" + pickupTypePre + "申请,审核未通过");
			detail.setOperator(FinanceSessionContext.getAccountFullName());
			detail.setOperatorId(FinanceSessionContext.getAccountId());
			detail.setOperatorRole(OperatorRoleEnum.ENTERPRISE);
			pickupProcess.setCurrentDetail(detail);
			return pickupProcess;
		} else {
			pickupProcess.setDescription(String.format(pickupTypePre + " %s 件,审核已通过", pickupProcess.getPickup()));
		}

		processType = ProcessTypeEnum.PLEDGE;
		processSegment = ProcessSegmentEnum.ARRIVE;
		FinanceProcessEntity arriveProcess = financeProcessService.inquireFinanceProcess(pickupEntity.getFinanceId(), processType, processSegment);
		if (audit) {
			arriveProcess.setPickupable(arriveProcess.getArrive().subtract(arriveProcess.getPickup()));
			if (arriveProcess.getPickupable().compareTo(BigDecimal.ZERO) < 0) {
				arriveProcess.setPickupable(BigDecimal.ZERO);
			}
		}
		String segment = "到港%s件,体积%.2f(m³),重量%.2f(kg),申请提货 %s件,已提 %s件,可提 %s件,异常 %s件";
		arriveProcess.setSegment(
				String.format(segment, arriveProcess.getArrive(), arriveProcess.getVolume(), arriveProcess.getWeight(), arriveProcess.getPickup(), arriveProcess.getSign(), arriveProcess.getPickupable(), arriveProcess.getAbnormal()));

		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(pickupEntity.getPickupId());
		detail.setBusinessType(BusinessTypeEnum.PICKUP_APPLICATION);
		detail.setDescription(String.format(pickupTypePre + "申请已通过,需还款 ￥%.2f 元", pickupEntity.getAuditAmount()));
		detail.setBusinessVoucher("--");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.ENTERPRISE);
		pickupProcess.setCurrentDetail(detail);
		pickupProcess.setParentProcess(arriveProcess);
		return pickupProcess;
	}

	/** 创建延期还款 */
	public static FinanceProcessDetailEntity fromPickupDelayApplication(PickupDelayApplicationEntity delay, Boolean audit, Boolean cancel) {
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = delay.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(delay.getFinanceId(), businessId, businessType, processType, processSegment);
		if (pickupProcess == null) {
			return null;
		}
		// 明细记录
		List<FinanceProcessDetailEntity> details = financeProcessDetailService.inquireFinanceProcessDetailList(pickupProcess.getProcessId(), businessId, businessType);
		FinanceProcessDetailEntity detail = null;
		String message = "审批中";
		if (audit != null && audit.booleanValue()) {
			message = "审批通过";
		} else if (audit != null && !audit.booleanValue()) {
			message = "审批未通过";
		} else if (cancel != null) {
			message = "取消申请";
		}
		if (details == null) {
			detail = new FinanceProcessDetailEntity();
			detail.setProcessId(pickupProcess.getProcessId());
			detail.setBusinessId(delay.getApplicantId());
			detail.setBusinessType(BusinessTypeEnum.PICKUP_DELAY);
			detail.setBusinessVoucher("--");
			detail.setOperator(FinanceSessionContext.getAccountFullName());
			detail.setOperatorId(FinanceSessionContext.getAccountId());
			detail.setOperatorRole(OperatorRoleEnum.ENTERPRISE);
		} else {
			detail = details.get(0);
		}
		String sourceDeliveryDate = DateUtil.formatDate(delay.getSourceDeliveryDate());
		String deliveryDate = DateUtil.formatDate(delay.getDeliveryDate());
		detail.setDescription(String.format("申请配送日期由 %s 延期至 %s 编号:%s %s", sourceDeliveryDate, deliveryDate, delay.getPickupDelayNumber(), message));
		return detail;
	}

	/** 还款通知 */
	public static FinanceProcessDetailEntity fromFinancePickupReceivablesProcess(PickupApplicationEntity pickupEntity, ReceivablesEntity receivablesEntity) {
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = pickupEntity.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(pickupEntity.getFinanceId(), businessId, businessType, processType, processSegment);
		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(receivablesEntity.getReceivablesId());
		detail.setBusinessType(BusinessTypeEnum.RECEIVABLES);
		detail.setDescription(String.format("用户还款 ￥%.2f 元", receivablesEntity.getBeneficiaryAmount()));
		detail.setBusinessVoucher("《收款单》");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.ENTERPRISE);
		detail.setProcessId(pickupProcess.getProcessId());
		return detail;
	}

	/** 放货通知动态信息 */
	public static FinanceProcessDetailEntity fromFinancePickupDeliveryNoticeProcessDetail(DeliveryNoticeEntity deliveryNotice) {
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = deliveryNotice.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(deliveryNotice.getFinanceId(), businessId, businessType, processType, processSegment);

		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(deliveryNotice.getDeliveryNoticeId());
		detail.setBusinessType(BusinessTypeEnum.DELIVERY_NOTICE);
		detail.setDescription("放货通知,通知单号:" + deliveryNotice.getDeliveryNoticeNumber());
		detail.setBusinessVoucher("《放货通知单》");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.LOGISTICS);
		detail.setProcessId(pickupProcess.getProcessId());
		return detail;
	}

	/** 放货通知动态信息 */
	public static FinanceProcessDetailEntity fromFinancePickupDeliveryProcessDetail(DeliveryEntity delivery) {
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = delivery.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(delivery.getFinanceId(), businessId, businessType, processType, processSegment);

		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(delivery.getDeliveryId());
		detail.setBusinessType(BusinessTypeEnum.DELIVERY);
		detail.setDescription("配送任务,单号:" + delivery.getDeliveryNumber());
		detail.setBusinessVoucher("《配送单》");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.LOGISTICS);
		detail.setProcessId(pickupProcess.getProcessId());
		return detail;
	}

	/** 签收动态信息 */
	public static FinanceProcessEntity fromFinancePickupSignProcess(ContainerInventoryEntity inventory) {
		ProcessTypeEnum processType = ProcessTypeEnum.PLEDGE;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.ARRIVE;
		FinanceProcessEntity arriveProcess = financeProcessService.inquireFinanceProcess(inventory.getFinanceId(), processType, processSegment);

		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		if (!inventory.validateAbnormal()) {
			List<ContainerBulkstockEntity> containerBulkstockList = containerBulkstockService.inquireContainerBulkstockList(inventory.getInventoryId());
			for (ContainerBulkstockEntity cbe : containerBulkstockList) {
				arriveProcess.setSign(arriveProcess.getSign().add(cbe.getQuantity()));
			}
		}
		arriveProcess.setPickupable(arriveProcess.getArrive().subtract(arriveProcess.getPickup()));
		if (arriveProcess.getPickupable().compareTo(BigDecimal.ZERO) < 0) {
			arriveProcess.setPickupable(BigDecimal.ZERO);
		}
		arriveProcess.setSegment(String.format("到港 %s件，申请提货 %s件，已提 %s件,可提 %s件", arriveProcess.getArrive(), arriveProcess.getPickup(), arriveProcess.getSign(), arriveProcess.getPickupable()));

		processType = ProcessTypeEnum.PLEDGE;
		processSegment = ProcessSegmentEnum.PICKUP;
		Long businessId = inventory.getPickupId();
		BusinessTypeEnum businessType = BusinessTypeEnum.PICKUP_APPLICATION;
		FinanceProcessEntity pickupProcess = financeProcessService.inquireFinanceProcess(inventory.getFinanceId(), businessId, businessType, processType, processSegment);
		pickupProcess.setDescription(String.format("提货 %s 件,已签收", pickupProcess.getPickup()));

		// 明细记录
		FinanceProcessDetailEntity detail = new FinanceProcessDetailEntity();
		detail.setBusinessId(inventory.getInventoryId());
		detail.setBusinessType(BusinessTypeEnum.CONTAINER_INVENTORY);
		detail.setDescription("签收");
		detail.setBusinessVoucher("《签收单》");
		detail.setOperator(FinanceSessionContext.getAccountFullName());
		detail.setOperatorId(FinanceSessionContext.getAccountId());
		detail.setOperatorRole(OperatorRoleEnum.LOGISTICS);
		detail.setProcessId(pickupProcess.getProcessId());

		pickupProcess.setParentProcess(arriveProcess);
		pickupProcess.setCurrentDetail(detail);
		return pickupProcess;
	}

	/** 创建动态信息-监管解除 */
	public static FinanceProcessEntity fromFinanceRelieveProcess(ContainerInventoryEntity inventory, boolean abnormal) {
		FinanceApplicationEntity finance = financeApplicationService.inquireFinanceApplicationEntity(inventory.getFinanceId());
		Long financeId = finance.getFinanceId();
		String financeNumber = finance.getFinanceNumber();
		Long inventoryId = inventory.getInventoryId();

		ProcessTypeEnum processType = ProcessTypeEnum.FINISHED;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.RELIEVE;
		FinanceProcessEntity process = financeProcessService.inquireFinanceProcess(financeId, processType, processSegment);
		if (process == null) {
			process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, null, null, null, null);
			process.setRelieve(BigDecimal.ZERO);
		}
		FinanceProcessDetailEntity currentDetail = new FinanceProcessDetailEntity();
		currentDetail.setBusinessId(inventoryId);
		currentDetail.setBusinessType(BusinessTypeEnum.SUPERVISION_RELIEVE);
		currentDetail.setBusinessVoucher("《监管解除通知》");

		StringBuffer sb = new StringBuffer("解除监管");
		if (abnormal) {
			sb.append("(异常处置)");
		}
		ContainerBulkstockService containerBulkstockService = ComponentFactory.loadClass(ContainerBulkstockService.class);
		List<ContainerBulkstockEntity> bulkstocks = containerBulkstockService.inquireContainerBulkstockList(inventoryId);
		String unit = "件";
		for (ContainerBulkstockEntity cbe : bulkstocks) {
			sb.append(" ").append(cbe.getBulkstockName()).append(cbe.getSpecification()).append(cbe.getQuantity()).append(cbe.getUnit());
			unit = cbe.getUnit();
			process.setRelieve(process.getRelieve().add(cbe.getQuantity()));
		}
		currentDetail.setDescription(sb.toString());
		currentDetail.setOperator(FinanceSessionContext.getAccountFullName());
		currentDetail.setOperatorId(FinanceSessionContext.getAccountId());
		currentDetail.setOperatorRole(OperatorRoleEnum.PLATFORM);
		process.setCurrentDetail(currentDetail);
		process.setSegment(String.format("解质:共已监管解除 %s %s", process.getRelieve(), unit));
		return process;
	}

	/** 创建动态信息-融资完成 */
	public static FinanceProcessEntity fromFinanceEndallProcess(Long financeId, String financeNumber) {
		ProcessTypeEnum processType = ProcessTypeEnum.FINISHED;
		ProcessSegmentEnum processSegment = ProcessSegmentEnum.ENDALL;
		BusinessTypeEnum businessType = BusinessTypeEnum.FINANCE;
		String businessVoucher = "《终止质押通知书》";
		String description = "融资项目已完成,并终止监管";
		FinanceProcessEntity process = createFinanceProcessEntity(financeId, financeNumber, processType, processSegment, financeId, businessType, businessVoucher, description);
		process.setSegment("质押终止");
		return process;
	}
}
